package net.Group.MembershipService;

import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import jxta.security.impl.cipher.SecretKey;
import jxta.security.impl.cipher.KeyBuilder;
import jxta.security.crypto.JxtaCrypto;
import jxta.security.impl.crypto.JxtaCryptoSuite;
import jxta.security.cipher.Cipher;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
        	
/**
 *  This class is used to create an Encrypted Documents.
 *  RC4 symmetric encryption is used by the factory.It 
 *  assumes that the legitimate recievers of the document share 
 *  the passphrase and will hence be able to decode the information
 */
	
public class EncryptedDocumentsFactory{

	private static final org.apache.log4j.Category LOG = 
		    org.apache.log4j.Category.getInstance(EncryptedDocumentsFactory.class.getName());
	
	/*
	 * This class just needs to serve as a factory and need be instantiated
	 * Hence the constructor is made private 
	 */
	private EncryptedDocumentsFactory(){
	}

	public static StructuredDocument getEncryptedDocument() throws 
								jxta.security.exceptions.CryptoException{

	    // We create an encrypted Document by using RC4 symmetric encryption
        // We share a secretPhrase with the Membership Service and it is the 
        // key used for encryption.

        // Secret shared with the Membership Service
        String sharedSecret = "Shared Secret Key";

    	// This is the data which we will encrypt    
		String dataToBeEncrypted = "Secret Data";

		// First build a key using the KeyBuilder , with RC4 as the algorithm
		SecretKey secretKey=(SecretKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RC4,
													KeyBuilder.LENGTH_RC4,false);
		// All Keys need to have a minimum length for a successful encryption
		int minimumKeyLength = secretKey.getLength();
		// If our key does not fulfill the minimum length requirement,
		// we need to pad zero byte values with it and make it long enough
		byte[] keyArray;
		if(sharedSecret.length()<minimumKeyLength){
			// In this case we have to pad the key such that it has the 
			// minimum key length. The new byte[] ensures that all bytes are 
			// initialized to 0X00
			keyArray = new byte[minimumKeyLength];
			System.arraycopy(sharedSecret.getBytes(),0,keyArray,0,sharedSecret.length());
		} else {
			// The key is more that the required length. Hence no concerns 
			keyArray =sharedSecret.getBytes();
		}
		// Set the secret key with our value
		secretKey.setKey(keyArray, 0);
		// From the JXTACrypto Suite , get the RC4 cipher algorithm
		JxtaCrypto crypto = new JxtaCryptoSuite(JxtaCrypto.MEMBER_RC4,
												       null, (byte)0, (byte)0);		
		Cipher rc4Algorithm = crypto.getJxtaCipher();
		
	    //Initialize the Algorithm with the key and required mode
		rc4Algorithm.init(secretKey, Cipher.MODE_ENCRYPT);
	    // Create a new byte[] to store the output
		byte[] outputBuffer = new byte[dataToBeEncrypted.length()];
	    // The actual encryption is done by this method
   	    rc4Algorithm.doFinal(dataToBeEncrypted.getBytes(), 0,
   	    					 dataToBeEncrypted.length(), outputBuffer, 0);
	    String encryptedData = new String(outputBuffer);
   	    LOG.debug("ENCRYPTED DATA => "+encryptedData);

   	    // Now we have successfully encrypted the method name.
   	    // Return a Structured Document using this method name
   	    MimeMediaType type = new MimeMediaType("text","xml");
        StructuredDocument doc =
                StructuredDocumentFactory.newStructuredDocument( type,"Apply" );
        Element e = doc.createElement("Data",encryptedData); 
        doc.appendChild( e );
        return doc;
	}	
	
}	
